package com.financing.service.invest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.financing.common.CONST;
import com.financing.components.payment.Gateway;
import com.financing.controller.invest.TradeController;
import com.financing.enums.finance.FinanceLogType;
import com.financing.enums.invest.InvestLogType;
import com.financing.enums.notify.AgentNotify;
import com.financing.enums.notify.AssetsNotify;
import com.financing.model.Data;
import com.financing.model.invest.Bid;
import com.financing.model.invest.Coupon;
import com.financing.model.invest.CouponLog;
import com.financing.model.user.User;
import com.financing.service.BaseService;
import com.financing.service.finance.FinanceLogService;
import com.financing.service.system.AssetsLogService;
import com.financing.util.DateUtil;
import com.financing.util.Money;
import com.financing.util.Str;
import com.financing.util.XmlHelper;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;

public class CouponLogService extends BaseService<Bid>{
	private AssetsLogService assetsLog = new AssetsLogService();	
    private static final Logger logger = Logger.getLogger(TradeController.class);

	 
	/**
	 * 获取投资可用的优惠券
	 */
	public List<CouponLog> available(int userId, Bid b) { 
		String time = DateUtil.getNowDateAndTime();
		User u = User.me.findById(userId);
		String sql = "select * from coupon_log where valid_start_time<=? and valid_end_time>=? and user_id=? and is_show='1' and status='normal' and (limit_amount<=? or type='tyj')"; 
		sql += Str.eq("experi", b.getType()) ? " and type='tyj' " : " and type<>'tyj' ";
		
		List<CouponLog> list = CouponLog.me.find(sql,time,time,userId,u.getAvailableAmount());
		List<CouponLog> res = new ArrayList<CouponLog>();
		list.forEach(n->{ 
			if(Str.contains(n.getAllowBid(), ","+b.getType()+",") 
				|| (Str.eq("public", b.getType()) && Str.contains(n.getAllowBid(), ","+b.getDayLimit()+"day,"))){
				res.add(n);
			}
		});
		return res;
	}
	
	/**
	 *  定向发放优惠券
	 */
	public boolean directSend(Coupon c, String amount, int userId, String remark){
		int amt = Integer.valueOf(amount);
		double left = Money.sub(c.getNum(), c.getApplyNum());
		if(left>=1){
			User u = User.me.findById(userId);
			CouponLog log = new CouponLog();
			log.setUserId(userId);
			log.setStatus("normal");
			log.setCouponId(c.getId());
			if(c.getValidDay()>0){
				Date now = new Date();
				log.setValidStartTime(now);
				log.setValidEndTime(DateUtil.adjust(now, c.getValidDay()));
			}else{
				log.setValidStartTime(c.getValidStartTime());
				log.setValidEndTime(c.getValidEndTime());
			}
			log.setIsShow(1);
			log.setType(c.getType());
			log.setAmount(amt);
			// 设置最低限额
			if(Str.ne("tyj", c.getType())) {
				JSONObject	json = JSON.parseObject(c.getLimitAmount());	
				double last = 0.0;
				double t = json.getDouble("target");
				String increase = json.getString("increase");
				if(Str.eq(increase, "1")) {
					double a = json.getDouble("amount");
					last = Money.mul((int) Money.div(amt, a), t);
				} else {
					last = t;
				}
				log.setLimitAmount(String.valueOf(last));
			} else {
				log.setLimitAmount(c.getLimitAmount());
			}
			log.setCreateTime(new Date());
			log.setAllowBid(c.getAllowBid());
			log.setAccess(c.getRule());
			log.setAllowBid(c.getAllowBid());
			log.setLink(c.getLink());
			log.setAccess("direct");
			log.setMobile(u.getMobile());
			log.setRealName(u.getRealName());
			log.setRemark(remark);

			if(log.save()) {

				// 插入资产记录-定向优惠券发放成功
				AssetsNotify notify = AssetsNotify.COUPON_DIRECT; 
				AgentNotify notify2 = AgentNotify.COUPON;
				assetsLog.bulid(User.me.findById(userId), Str.format(notify.getName(), log.getName()), Str.format(notify.getContents(), log.getName()), Str.format(notify2.getContents(), u.getMobile()+"（"+u.getRealName()+"）", "定向", log.getName()));
				
				// 更新数量
				c.setApplyNum(Money.add(c.getApplyNum(), 1.0)).update();

				// 插入体验金交易记录
				if(Str.eq("tyj", log.getType())) {
					InvestLogService.build("体验金", InvestLogType.TYJ, log.getId(), Double.valueOf(amount), userId, "success", "体验金奖励", "");
				}
			}
			return true;
		}else{
			logger.error(c.getId()+c.getName()+"加息券优惠券数量不足！");
			return false;
		}
	}
	
	/**
	 *  定向发送现金红包
	 */
	public boolean cashSend(String amount, int userId, User operator, String remark) throws Exception{
		int amt = Integer.valueOf(amount);
		User u = User.me.findById(userId);
		if(u!=null && amt>0) {
			XmlHelper res = Gateway.pay(CONST.PLAT_CODE, u.getCode(),amt, "现金奖励",true,false);
			
			if(res.isSuccess()) {
				
				// 插入优惠券记录
				CouponLog log = new CouponLog();
				log.setUserId(userId);
				log.setStatus("used");
				log.setCouponId(0);
				log.setIsShow(1);
				log.setType("xjhb");
				log.setAmount(amt);
				log.setLimitAmount("0");
				log.setCreateTime(new Date());
				log.setAllowBid("0");
				log.setAccess("");
				log.setAllowBid("");
				log.setLink("");
				log.setAccess("direct");
				log.setMobile(u.getMobile());
				log.setRealName(u.getRealName());
				log.setRemark(remark);
				log.save();
				
				// 插入交易记录
				InvestLogService.build("现金", InvestLogType.XJHB, 0, amt, userId, "success", "现金", res.getCode());
				
				// 插入财务记录
				FinanceLogService.build(User.me.findById(4), u, amt, res.getCode(), FinanceLogType.XJHB, "现金");
				
				// 插入资产记录-现金奖励发放成功
				AssetsNotify notify = AssetsNotify.CASH; 
				AgentNotify notify2 = AgentNotify.CASH; 
				assetsLog.bulid(u, notify.getName(), Str.format(notify.getContents(), amt), Str.format(notify2.getContents(), u.getMobile()+"（"+u.getRealName()+"）", amt));
				
				return true;
			}
		}
		return false;
	}

	/**
	 * 获取用户的优惠券
	 */
	public Page<CouponLog> findByUser(int page, int size, int userId, String type) {
		return CouponLog.me.paginate(page, size, "select *", "from coupon_log where user_id=? AND type=? AND is_show=1", userId, type);
	}

	/**
	 * 分页信息
	 */
	public Page<CouponLog> list(int page, int size, Map<String, String> map) {
		return CouponLog.me.paginate(page, size, buildSql("coupon_log",Arrays.asList("real_name", "create_time","is_show","user_id","mobile","status","type","coupon_id"),map));
	}
	
	/**
	 * 清除已失效优惠券记录
	 */
	public boolean clearByType(int userId) {
		return Db.update("update coupon_log set is_show = 0 where user_id = ? AND status = 'expire' ", userId)>0;
	}
	
	/**
	 * 转换标的可用条件名称
	 */
	public void transTagName(List<CouponLog> list) {
		Map<String,String> allowBidMap = 
			Data.putStr("public","常规标","first","新手标","experi","体验标","30day","1月标","45day","45天标","60day","2月标","90day","3月标","180day","6月标","210day","7月标","360day","12月标");
		list.forEach(n->{
			String v = "";
			if(Str.nb(n.getAllowBid())){
				for(String key : n.getAllowBid().split(",")){
					if(StringUtils.isNotBlank(key)){
						v += allowBidMap.get(key)+"、";
					}
				}
				n.setAllowBid(v.length()>0 ?v.substring(0, v.length()-1)+"可用":v);
			}
			
			// 转换最低限额说明
			n.setLimitAmount("满"+n.getLimitAmount()+"元可用");
		});	
	}
	
	/**
	 * 查找即将过期的优惠券
	 */
	public List<CouponLog> findCloseToExpire() {
		Date start = new Date();
		String end = DateUtil.adjust(start, 1, "yyyy-MM-dd");
		return CouponLog.me.find("select * from coupon_log where valid_end_time>=?  and valid_end_time<=? and status='normal' and is_notify=0 and is_show=1 ", DateUtil.format(start), end+" 23:59:59");
	}

	/**
	 * 查找过期的优惠券
	 */
	public List<CouponLog> findExpire() {
		Date start = new Date();
		return CouponLog.me.find("select * from coupon_log where valid_end_time<? and status='normal' ", DateUtil.format(start));
	}

	/**
	 * 发现用户可用的优惠券
	 */
	public List<CouponLog> findEnable(User u) {
		return CouponLog.me.find("select * from coupon_log where user_id=? and status='normal'", u.getId());
	}

	/**
	 * 统计优惠券数据
	 */
	public long sumByType(User u, String type) {
		BigDecimal bd = CouponLog.me.findFirst("select sum(amount) as total from coupon_log where user_id=? and type=?", u.getId(), type).getBigDecimal("total");
		return bd!=null ? bd.longValue() : 0;
	}
}
